/*
 * by wlh 
 * date 2025/09/18 16:10
 */
using System.Collections.Generic;
using System.Linq;
using UnityEditor.Experimental.GraphView;
using UnityEngine;

public static class GraphLayout
{
    // 自动排列所有节点（从左到右）
    public static void OrganizeNodesLeftToRight(GraphView graphView)
    {
        var nodes = graphView.nodes.ToList().Cast<Node>().ToList();
        var edges = graphView.edges.ToList();

        if (nodes.Count == 0) return;

        // 1. 识别真正的根节点（没有输入连接的节点）
        var rootNodes = FindTrueRootNodes(nodes, edges);

        // 2. 计算每个节点的层级（使用深度优先搜索）
        Dictionary<Node, int> nodeLevels = CalculateNodeLevelsDFS(nodes, edges, rootNodes);

        // 3. 按层级分组
        var levels = GroupNodesByLevel(nodeLevels);

        // 4. 从左到右排列节点
        ArrangeNodesLeftToRight(levels, graphView);
    }

    // 查找真正的根节点（没有输入连接的节点）
    private static List<Node> FindTrueRootNodes(List<Node> nodes, List<Edge> edges)
    {
        var rootNodes = new List<Node>();

        foreach (var node in nodes)
        {
            bool hasInput = edges.Any(edge =>
                edge.input != null &&
                edge.input.node == node);

            if (!hasInput)
            {
                rootNodes.Add(node);
            }
        }

        return rootNodes;
    }

    // 使用深度优先搜索计算每个节点的层级
    private static Dictionary<Node, int> CalculateNodeLevelsDFS(List<Node> nodes, List<Edge> edges, List<Node> rootNodes)
    {
        var levels = new Dictionary<Node, int>();
        var visited = new HashSet<Node>();

        // 初始化所有节点层级为-1（未访问）
        foreach (var node in nodes)
        {
            levels[node] = -1;
        }

        // 为根节点设置层级0
        foreach (var root in rootNodes)
        {
            levels[root] = 0;
            DFS(root, 0, edges, levels, visited);
        }

        // 处理孤立节点（没有连接的节点）
        foreach (var node in nodes)
        {
            if (levels[node] == -1)
            {
                // 找到最大层级，将孤立节点放在最右边
                int maxLevel = levels.Values.Where(l => l >= 0).DefaultIfEmpty(0).Max();
                levels[node] = maxLevel + 1;
            }
        }

        return levels;
    }

    // 深度优先搜索辅助函数
    private static void DFS(Node currentNode, int currentLevel, List<Edge> edges, Dictionary<Node, int> levels, HashSet<Node> visited)
    {
        if (visited.Contains(currentNode)) return;

        visited.Add(currentNode);
        levels[currentNode] = currentLevel;

        // 查找当前节点的所有输出连接
        var outputEdges = edges.Where(edge =>
            edge.output != null &&
            edge.output.node == currentNode);

        foreach (var edge in outputEdges)
        {
            if (edge.input != null && edge.input.node is Node targetNode)
            {
                // 如果目标节点已经有更小的层级，则保持不变
                if (levels[targetNode] < currentLevel + 1)
                {
                    levels[targetNode] = currentLevel + 1;
                }

                DFS(targetNode, currentLevel + 1, edges, levels, visited);
            }
        }
    }

    // 按层级分组节点
    private static Dictionary<int, List<Node>> GroupNodesByLevel(Dictionary<Node, int> nodeLevels)
    {
        var levels = new Dictionary<int, List<Node>>();

        foreach (var kvp in nodeLevels)
        {
            if (!levels.ContainsKey(kvp.Value))
            {
                levels[kvp.Value] = new List<Node>();
            }

            levels[kvp.Value].Add(kvp.Key);
        }

        return levels;
    }

    // 从左到右排列节点
    private static void ArrangeNodesLeftToRight(Dictionary<int, List<Node>> levels, GraphView graphView)
    {
        // 布局参数
        const float levelSpacing = 300f; // 层级之间的水平间距
        const float nodeSpacing = 150f;  // 同一层级节点之间的垂直间距
        const float startX = 100f;       // 起始X坐标
        const float startY = 100f;       // 起始Y坐标

        // 计算每个层级的最大节点数，用于垂直居中
        int maxNodesInLevel = levels.Values.Max(levelNodes => levelNodes.Count);
        float totalHeight = maxNodesInLevel * nodeSpacing;

        // 按层级排序（从左到右）
        var sortedLevels = levels.OrderBy(l => l.Key).ToList();

        // 排列每个层级的节点
        for (int levelIndex = 0; levelIndex < sortedLevels.Count; levelIndex++)
        {
            var level = sortedLevels[levelIndex];
            float levelX = startX + levelIndex * levelSpacing;
            int nodeCount = level.Value.Count;

            // 计算起始Y坐标，使节点在垂直方向居中
            float levelStartY = startY + (totalHeight - nodeCount * nodeSpacing) / 2;

            // 排列当前层级的所有节点
            for (int i = 0; i < nodeCount; i++)
            {
                Node node = level.Value[i];
                float nodeY = levelStartY + i * nodeSpacing;

                // 设置节点位置
                node.SetPosition(new Rect(levelX, nodeY, 0, 0));
            }
        }
    }

    // 简单网格布局（从左到右排列）
    public static void SimpleLeftToRightLayout(GraphView graphView, int maxNodesPerRow = 4)
    {
        var nodes = graphView.nodes.ToList().Cast<Node>().ToList();
        if (nodes.Count == 0) return;

        const float nodeWidth = 200f;
        const float nodeHeight = 100f;
        const float horizontalSpacing = 250f;
        const float verticalSpacing = 150f;
        const float startX = 100f;
        const float startY = 100f;

        for (int i = 0; i < nodes.Count; i++)
        {
            int row = i / maxNodesPerRow;
            int col = i % maxNodesPerRow;

            float x = startX + col * horizontalSpacing;
            float y = startY + row * verticalSpacing;

            nodes[i].SetPosition(new Rect(x, y, nodeWidth, nodeHeight));
        }
    }
}
